-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.


local c_fan_object = require 'fan_object'
local c_fan_type_object = require 'fan_type_object'
local c_fans_object = require 'fans_object'
local c_fan_group_object = require 'fan_group_object'
local c_valve = require 'valve_object'
local c_valves = require 'valves_object'
local object_path = require 'dbus.object_path'
local signal = require 'mc.signal'
local c_basic_cooling_config = require 'basic_cooling_config'

local m = {}

function m.create_mds_object(object_name, props, parent, path)
    local property_changed = signal.new()
    return setmetatable({
        props = props,
        persist_data = {},
        props_set_by_cb = {},
        get_property_memory_value = function(self)
        end
    }, {
        __index = function(self, name)
            if name == 'get_object_name' then
                return function()
                    return object_name
                end
            elseif name == 'get_parent' then
                return function()
                    return parent
                end
            elseif name == 'path' then
                return path
            elseif name == 'property_changed' then
                return property_changed
            elseif name == 'register_mdb_objects' then
                return function ()
                end
            end
            return self.props[name]
        end,
        __newindex = function(self, name, value)
            if self.props[name] ~= value then
                self.props[name] = value
                property_changed:emit(name, value)
            end
        end
    })
end

local fan_path<const> = '/bmc/kepler/Systems/1/Thermal/Fans/Fan_1_010107'
local fan_type_path<const> = '/bmc/kepler/Systems/1/Thermal/FanTypes/FanType_1_010107'

function m.add_fan_obj(object_manage, object_name, props, position, parent, path)
    local obj = m.create_mds_object(object_name, props, parent, path or fan_path)
    object_manage.mc:before_add_object(c_fan_object.__class_name, obj)
    object_manage.mc:add_object(c_fan_object.__class_name, obj, position)
    return obj
end

function m.add_fan_type_obj(object_manage, object_name, props, position, parent, path)
    local obj = m.create_mds_object(object_name, props, parent, path or fan_type_path)
    object_manage.mc:before_add_object(c_fan_type_object.__class_name, obj)
    object_manage.mc:add_object(c_fan_type_object.__class_name, obj, position)
    return obj
end

function m.add_fans_obj(object_manage, object_name, props, position, parent, path)
    local obj = m.create_mds_object(object_name, props, parent, path )
    object_manage.mc:before_add_object(c_fans_object.__class_name, obj)
    object_manage.mc:add_object(c_fans_object.__class_name, obj, position)
    return obj
end

function m.add_fan_group_obj(object_manage, object_name, props, position, parent, path)
    local obj = m.create_mds_object(object_name, props, parent, path )
    object_manage.mc:before_add_object(c_fan_group_object.__class_name, obj)
    object_manage.mc:add_object(c_fan_group_object.__class_name, obj, position)
    return obj
end

function m.add_basic_cooling_config_obj(object_manage, object_name, props, position, parent, path)
    local obj = m.create_mds_object(object_name, props, parent, path )
    object_manage.mc:before_add_object(c_basic_cooling_coinfig.__class_name, obj)
    object_manage.mc:add_object(c_basic_cooling_coinfig.__class_name, obj, position)
    return obj
end

function m.add_valve_obj(object_manage, object_name, props, position, parent, path)
    local obj = m.create_mds_object(object_name, props, parent, path )
    object_manage.mc:before_add_object(c_valve.__class_name, obj)
    object_manage.mc:add_object(c_valve.__class_name, obj, position)
    return obj
end

function m.add_valves_obj(object_manage, object_name, props, position, parent, path)
    local obj = m.create_mds_object(object_name, props, parent, path )
    object_manage.mc:before_add_object(c_valves.__class_name, obj)
    object_manage.mc:add_object(c_valves.__class_name, obj, position)
    return obj
end

function m.add_object_complete(object_manage, position)
    object_manage.mc:add_object_complete(position)
end

return m
